//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <ddk.h>
#include "ddktstmemory.h"
#include "ddktstserver.h"

EXTERN Boolean g_bError;
EXTERN ControlPack g_ArgPack[ALLOC_MAX_NUM];

ECode g_err = NOERROR;

Boolean mallocFun1()
{
    int i, j = 0;

    for (i = 0; i < ALLOC_MAX_NUM; i++, j++) {
        g_ArgPack[i].FuncNo = MemTst_malloc;
        g_ArgPack[i].size = j % (c_uMaxAllocationSize + 1);

        g_bError = !AllocFun(&g_ArgPack[i]);
        if (g_bError) break;
    }

    FreeAllAllocMem();

    return 0;
}

Boolean mallocFun2()
{
    for (int i = 0; i < ALLOC_MAX_NUM; i++) {
        g_ArgPack[i].FuncNo = MemTst_malloc;
        g_ArgPack[i].size = Rand() % (c_uMaxAllocationSize + 1);

        g_bError = !AllocFun(&g_ArgPack[i]);
        if (g_bError) break;
    }

    FreeAllAllocMem();

    return 0;
}

Boolean mallocFun3()
{
    Boolean bm = FALSE;
    ControlPack ArgPack;
    ArgPack.size = 4093;
    ArgPack.va = malloc(ArgPack.size);
    bm = (Boolean)ArgPack.va;
    if (bm) {
        free(ArgPack.va);
    }
    else {
        kprintf("malloc failed\n");
        g_bError = TRUE;
    }

    return 0;
}

int mallocFun4Thread(void *arg)
{
    Boolean bm = FALSE;
    int i;
    int nNum = (int)arg;
    ControlPack *ArgPack = new ControlPack[nNum];
    memset(ArgPack, 0, sizeof(ControlPack) * nNum);

    for (i = 0; i < nNum; i++) {
        ArgPack[i].FuncNo = MemTst_malloc;
        ArgPack[i].size = Rand() % (c_uMaxAllocationSize + 1);

        bm = AllocFun(&ArgPack[i]);
        if (!bm) {
            g_bError = TRUE;
            break;
        }
        FreeFun(&ArgPack[i]);
    }

    if (ArgPack) delete []ArgPack;
    return bm;
}
Boolean mallocFun4()
{
    int nNum = 5;
    const int nThreadNum = 5;
    ECode ec = NOERROR;

    IThread *pmallocFun4Thd[nThreadNum];
    for (int i = 0; i < nThreadNum; i++) {
        ec = DzCreateKernelThread(mallocFun4Thread,
                                  (void *)nNum,
                                  CreateThreadFlag_System,
                                  ThreadPriorityRank_Normal,
                                  &pmallocFun4Thd[i]);
        if (FAILED(ec)) {
            kprintf("CreateKernelThread error\n");
            g_bError = TRUE;
        }
    }

    for (int i = 0; i < nThreadNum; i++) {
        if (pmallocFun4Thd[i]) {
            pmallocFun4Thd[i]->Join(INFINITE, NULL);
            pmallocFun4Thd[i]->Release();
        }
    }

    return 0;
}

Boolean mallocFun5()
{
    const int ArgPackNum = 10;
    ControlPack ArgPack[ArgPackNum];

    for (int i = 0; i < ArgPackNum; i++) {
        ArgPack[i].FuncNo = MemTst_malloc;
        ArgPack[i].size = Rand() % (c_uMaxAllocationSize + 1);

        g_bError = !AllocFun(&ArgPack[i]);
        if (g_bError) break;
        FreeFun(&ArgPack[i]);
    }

    return 0;
}

//=============================================================================
Address vFixAddr = 0x50000000;
Address VGAIoAddr = 0x000B8000;
UInt32 uSize = 4 * 1024;
Address virAddr;
Boolean IoRemapFun1()
{
    g_err = DzIoRemap(vFixAddr, uSize, VGAIoAddr, MemoryMap_Upgrow,
        MemoryProtection_Read, &virAddr);
    if (NOERROR != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    g_err = DzIoUnmap(virAddr, uSize);
    if (NOERROR != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    return 0;
}

Boolean IoRemapFun2()
{
    g_err = DzIoRemap(vFixAddr, uSize, VGAIoAddr, MemoryMap_Downgrow,
                    MemoryProtection_RW, &virAddr);
    if (NOERROR != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    g_err = DzIoUnmap(virAddr, uSize);
    if (NOERROR != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    return 0;
}

Boolean IoRemapFun3()
{
    g_err = DzIoRemap(vFixAddr, uSize, VGAIoAddr, MemoryMap_Upgrow,
                    MemoryProtection_IO, &virAddr);
    if (NOERROR != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    g_err = DzIoUnmap(virAddr, uSize);
    if (NOERROR != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    return 0;
}

Boolean IoRemapFun4()
{
    g_err = DzIoRemap(vFixAddr, uSize, VGAIoAddr, MemoryMap_Downgrow,
                    MemoryProtection_RWIO, &virAddr);
    if (NOERROR != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    g_err = DzIoUnmap(virAddr, uSize);
    if (NOERROR != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    return 0;
}

Boolean IoRemapFun5()
{
    g_err = DzIoRemap(vFixAddr, uSize, VGAIoAddr, MemoryMap_Upgrow,
                    (MemoryProtection)0, &virAddr);
    if (E_INVALID_ARGUMENT != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    return 0;
}

Boolean IoRemapFun6()
{
    Address virAddr2;
    g_err = DzIoRemap(vFixAddr, uSize, VGAIoAddr, MemoryMap_Fixed,
                    MemoryProtection_Read, &virAddr);
    if (NOERROR != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    g_err = DzIoRemap(vFixAddr, uSize, VGAIoAddr, MemoryMap_Fixed,
                    MemoryProtection_Read, &virAddr2);
    if (g_err != E_ALREADY_EXIST) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        DzIoUnmap(virAddr, uSize);
        return 1;
    }

    g_err = DzIoUnmap(virAddr, uSize);
    if (NOERROR != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    return 0;
}

Boolean IoRemapFun7()
{
    g_err = DzIoRemap(vFixAddr + 1, uSize, VGAIoAddr, MemoryMap_Downgrow,
                    MemoryProtection_IO, &virAddr);
    if (E_INVALID_ARGUMENT != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    return 0;
}

Boolean IoRemapFun8()
{
    Address vRandAddr;
    do {
        vRandAddr = ((Rand() % (0x80000000 + 1)) / 4096) * 4096;
    } while ((vRandAddr >= 0x42010000) && (vRandAddr <= 0x5FFF0000));

    g_err = DzIoRemap(vRandAddr, uSize, VGAIoAddr, MemoryMap_Fixed,
                    MemoryProtection_IO, &virAddr);
    if (E_INVALID_ARGUMENT != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    g_err = DzIoUnmap(vRandAddr, uSize);
    if (E_INVALID_ARGUMENT != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    return 0;
}

Boolean IoRemapFun9()
{
    g_err = DzIoRemap(vFixAddr, uSize + 1, VGAIoAddr, MemoryMap_Upgrow,
                    MemoryProtection_IO, &virAddr);
    if (E_INVALID_ARGUMENT != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    return 0;
}

Boolean IoRemapFun10()
{
    g_err = DzIoRemap(vFixAddr, 0, VGAIoAddr, MemoryMap_Downgrow,
                    MemoryProtection_IO, &virAddr);
    if (E_INVALID_ARGUMENT != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    return 0;
}

Boolean IoRemapFun11()
{
    g_err = DzIoRemap(vFixAddr, 0x1DFE0000 + 0x1000, VGAIoAddr,
                    MemoryMap_Upgrow, MemoryProtection_IO, &virAddr);
    if (g_err != E_NOT_ENOUGH_ADDRESS_SPACE) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    return 0;
}

Boolean IoRemapFun12()
{
    g_err = DzIoRemap(vFixAddr, uSize, VGAIoAddr, MemoryMap_Downgrow,
                    MemoryProtection_IO, NULL);
    if (E_INVALID_ARGUMENT != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    return 0;
}

Boolean IoRemapFun13()
{
    g_err = DzIoRemap(vFixAddr, uSize, VGAIoAddr, MemoryMap_Upgrow,
                    MemoryProtection_Read, &virAddr);
    if (NOERROR != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    g_err = DzIoUnmap(virAddr, uSize);
    if (NOERROR != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }
    g_err = DzIoUnmap(virAddr, uSize);
    if (E_INVALID_ARGUMENT != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    return 0;
}

Boolean IoRemapFun14()
{
    g_err = DzIoRemap(vFixAddr, uSize, VGAIoAddr, MemoryMap_Upgrow,
                    MemoryProtection_Read, &virAddr);
    if (NOERROR != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    g_err = DzIoUnmap(virAddr + 1, uSize);
    if (E_INVALID_ARGUMENT != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
    }

    g_err = DzIoUnmap(virAddr, 0);
    if (E_INVALID_ARGUMENT != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
    }

    g_err = DzIoUnmap(virAddr, uSize - 0x1000);
    if (E_INVALID_ARGUMENT != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
    }

    g_err = DzIoUnmap(virAddr, uSize + 0x1000);
    if (E_INVALID_ARGUMENT != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
    }

    g_err = DzIoUnmap(virAddr, uSize + 1);
    if (E_INVALID_ARGUMENT != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
    }

    g_err = DzIoUnmap(virAddr, uSize);
    if (NOERROR != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    return 0;
}

Boolean IoRemapFun15()
{
    const int RUNTIMES = 10000;
    for (int i = 0; i < RUNTIMES; i++) {
        g_err = DzIoRemap(vFixAddr, uSize, VGAIoAddr, MemoryMap_Upgrow,
                        MemoryProtection_Read, &virAddr);
        if (NOERROR != g_err) {
            g_bError = TRUE;
            kprintf("%d, %x\n", __LINE__, g_err);
            return 1;
        }

        g_err = DzIoUnmap(virAddr, uSize);
        if (NOERROR != g_err) {
            g_bError = TRUE;
            kprintf("%d, %x\n", __LINE__, g_err);
            return 1;
        }
    }

    return 0;
}

Boolean IoRemapFun16()
{
    const int RUNTIMES = 10000;

    for (int i = 0; i < RUNTIMES; i++) {
        g_err = DzIoRemap(vFixAddr, uSize, VGAIoAddr, MemoryMap_Fixed, 
                        MemoryProtection_Read, &virAddr);
        if (NOERROR != g_err) {
            g_bError = TRUE;
            kprintf("%d, %x, times: %d\n", __LINE__, g_err, i);
            return 1;
        }

        g_err = DzIoUnmap(virAddr, uSize);
        if (NOERROR != g_err) {
            g_bError = TRUE;
            kprintf("%d, %x, times: %d\n", __LINE__, g_err, i);
            return 1;
        }
    }

    return 0;
}

//=============================================================================
virtaddr_t virtKerAddr;
Boolean KIoRemapFun1()
{
    virtKerAddr = DzKIoRemap(vFixAddr, uSize);
    if (NULL == virtKerAddr) {
        g_bError = TRUE;
        kprintf("%d\n", __LINE__);
        return 1;
    }

    DzKIoUnmap(virtKerAddr);

    return 0;
}

Boolean KIoRemapFun2()
{
    virtKerAddr = DzKIoRemap(vFixAddr, uSize + 1);
    if (NULL != virtKerAddr) {
        g_bError = TRUE;
        kprintf("%d\n", __LINE__);
        return 1;
    }

    return 0;
}

Boolean KIoRemapFun3()
{
    virtKerAddr = DzKIoRemap(vFixAddr, 0);
    if (NULL != virtKerAddr) {
        g_bError = TRUE;
        kprintf("%d\n", __LINE__);
        return 1;
    }

    return 0;
}

Boolean KIoRemapFun4()
{
    g_err = DzIoRemap(vFixAddr, uSize, VGAIoAddr, MemoryMap_Upgrow,
                    MemoryProtection_IO, &virAddr);
    if (NOERROR != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    DzKIoUnmap(&virAddr);

    g_err = DzIoUnmap(virAddr, uSize);
    if (NOERROR != g_err) {
        g_bError = TRUE;
        kprintf("%d, %x\n", __LINE__, g_err);
        return 1;
    }

    return 0;
}

Boolean KIoRemapFun5()
{
    virtKerAddr = DzKIoRemap(vFixAddr, uSize);
    if (NULL == virtKerAddr) {
        g_bError = TRUE;
        kprintf("%d\n", __LINE__);
        return 1;
    }

    DzKIoUnmap(virtKerAddr);
    DzKIoUnmap(virtKerAddr);

    return 0;
}

Boolean KIoRemapFun6()
{
    const int nRunTimes = 10000;

    for (int i = 0; i < nRunTimes; i++) {
        virtKerAddr = DzKIoRemap(vFixAddr, uSize);
        if (NULL == virtKerAddr) {
            g_bError = TRUE;
            kprintf("%d\n", __LINE__);
            return 1;
        }

        DzKIoUnmap(virtKerAddr);
    }

    return 0;
}
